//
const ssr = require('../namespace/SSRLoSNamespace');

var LOS_RENDER_TYPE = cc.Enum(
    {
        "SIGHT_AREA"                        : 0,
        "SIGHT_VERT"                        : 1,
        "BLOCKING_EDGE"                     : 2,
        "POTENTIAL_BLOCKING_EDGE"           : 3,
        "VISIBLE_EDGE"                      : 4,
        "HIT_POINT"                         : 5,
        "RAY"                               : 6,
        "SIGHT_RANGE"                       : 7,
        "SIGHT_LIGHT"                       : 8,
    }
);

ssr.LoS.Component.Render = cc.Class({
    extends: cc.Component,
    editor: CC_EDITOR && {
        menu: 'ssr/LoS/Render',
    },
    properties: {
        target: {
            default         : null,
            type            : cc.Node
        },
        render: {
            default         : null,
            type            : cc.Graphics
        },
        mode: {
            default         : LOS_RENDER_TYPE.SIGHT_AREA,
            type            : LOS_RENDER_TYPE
        },
        isIgnoreSourcePosition: {
            default         : false
        },
        _srcBlendFactor: cc.macro.BlendFactor.SRC_COLOR,
        _dstBlendFactor: cc.macro.BlendFactor.ONE_MINUS_SRC_COLOR,
        srcBlendFactor: {
            get () {
                return this._srcBlendFactor;
            },
            set (value) {
                if (this._srcBlendFactor === value) return;
                this._srcBlendFactor = value;
            }
        },
        dstBlendFactor: {
            get () {
                return this._dstBlendFactor;
            },
            set (value) {
                if (this._dstBlendFactor === value) return;
                this._dstBlendFactor = value;
            }
        },
    },
    onLoad:function() {
    },
    start:function() {
        if (this.mode == LOS_RENDER_TYPE.SIGHT_LIGHT) {
            this._loadLightEffect();   
        }
        var losCoreComponent = this.target ? this.target.getComponent("SSRLoSComponentCore") : null;
        if (losCoreComponent) {
            this._losCore = losCoreComponent.getLoSCore();
        }
        if (!this.render) {
            this.render = this.node.getComponent("cc.Graphics");
        }
    },
    update:function(dt) {
        if (!this.render || !this._losCore) {
            return;
        }
        var isUpdated = this._losCore.isUpdated();
        if (isUpdated || this._lightEffectAsset) {
            this.plot();
        }
    },
    clear:function() {
        this.render.clear();
    },
    plot:function() {
        if (!this.node.active) {
            return;
        }
        this.render.clear();
        //
        if (this.mode == LOS_RENDER_TYPE.SIGHT_AREA) {
            ssr.LoS.Render.Util.renderSightArea(this._losCore, this.render, this.isIgnoreSourcePosition);
        }
        else if (this.mode == LOS_RENDER_TYPE.SIGHT_VERT) {
            ssr.LoS.Render.Util.renderSightVert(this._losCore, this.render, this.isIgnoreSourcePosition);
        }
        else if (this.mode == LOS_RENDER_TYPE.BLOCKING_EDGE) {
            ssr.LoS.Render.Util.renderBlockingEdge(this._losCore, this.render, this.isIgnoreSourcePosition);
        }
        else if (this.mode == LOS_RENDER_TYPE.POTENTIAL_BLOCKING_EDGE) {
            ssr.LoS.Render.Util.renderPotentialBlockingEdge(this._losCore, this.render, this.isIgnoreSourcePosition);
        }
        else if (this.mode == LOS_RENDER_TYPE.VISIBLE_EDGE) {
            ssr.LoS.Render.Util.renderVisibleEdge(this._losCore, this.render, this.isIgnoreSourcePosition);
        }
        else if (this.mode == LOS_RENDER_TYPE.HIT_POINT) {
            ssr.LoS.Render.Util.renderHitPoint(this._losCore, this.render, this.isIgnoreSourcePosition);
        }
        else if (this.mode == LOS_RENDER_TYPE.RAY) {
            ssr.LoS.Render.Util.renderRay(this._losCore, this.render, this.isIgnoreSourcePosition, this.target);
        }
        else if (this.mode == LOS_RENDER_TYPE.SIGHT_RANGE) {
            ssr.LoS.Render.Util.renderSightRange(this._losCore, this.render, this.isIgnoreSourcePosition);
        }
        else if (this.mode == LOS_RENDER_TYPE.SIGHT_LIGHT) {
            if (this._lightEffectAsset) {
                this._updateLightEffect();
                ssr.LoS.Render.Util.renderSightArea(this._losCore, this.render, this.isIgnoreSourcePosition);
            }
        }
    },
    _loadLightEffect:function() {
        var self = this;
        cc.loader.loadRes("line-of-sight/shader/light", cc.EffectAsset, null, function(error, asset) {
            self._lightEffectAsset = asset;
            self._applyLightEffect();
            ssr.LoS.Render.Util.renderSightArea(self._losCore, self.render);
        });
    },
    _applyLightEffect:function() {
        if (!this.render) {
            this.render = this.node.getComponent("cc.Graphics");
        }
        var material = new cc.Material();
        material.effectAsset = this._lightEffectAsset;
        material.name = "light";
        this.render.setMaterial(0, material);
        /*
            BLEND_ZERO: 0,
            BLEND_ONE: 1,
            BLEND_SRC_COLOR: 768,
            BLEND_ONE_MINUS_SRC_COLOR: 769,
            BLEND_DST_COLOR: 774,
            BLEND_ONE_MINUS_DST_COLOR: 775,
            BLEND_SRC_ALPHA: 770,
            BLEND_ONE_MINUS_SRC_ALPHA: 771,
            BLEND_DST_ALPHA: 772,
            BLEND_ONE_MINUS_DST_ALPHA: 773,

            768/769
        */
        material.setBlend(
            true,
            cc.gfx.BLEND_FUNC_ADD,
            this.srcBlendFactor, this.dstBlendFactor,
            cc.gfx.BLEND_FUNC_ADD,
            this.srcBlendFactor, this.dstBlendFactor
        );
        this._updateLightEffect();
    },
    _updateLightEffect:function() {
        if (!this.render) {
            this.render = this.node.getComponent("cc.Graphics");
        }
        var material = this.render.getMaterial(0);
        var frameSize = cc.view.getFrameSize();
        var visibleSize = cc.view.getVisibleSize();
        var retinaFactor = cc.view.getDevicePixelRatio();
        var position = this.target.convertToWorldSpaceAR(cc.v2(0, 0));
        var centerx = position.x * frameSize.width / visibleSize.width * retinaFactor;
        var centery = position.y * frameSize.height / visibleSize.height * retinaFactor;
        material.setProperty("center", [centerx, centery]);
        var radius = this._losCore.getRadius();
        if (radius == -1) {
            var rect = this._losCore.getSightRect();
            radius = Math.sqrt(rect.width * rect.width, rect.height * rect.height);
            material.setProperty("radius", radius);
            material.setProperty("sourceRadius", 10);
            material.setProperty("intensity", 0.8);
        }
        else {
            material.setProperty("radius", radius * 2);
            material.setProperty("sourceRadius", radius * 0.1);
            material.setProperty("intensity", 0.8);
        }
    },
    getRender:function() {
        return this.render;
    }
});
